package myexchange

import org.springframework.transaction.annotation.Transactional;

import groovy.util.logging.Log;

class CardService {

    GameService gameService
	
	static transactional = false
	
	@Transactional
	public List<Card> setupCards(int numberOfPlayers){
		def shares = Share.list();
		shares.each{
			createCards(it)
		}
		return Card.list()
		
		
	}
	
	private void createCards(Share s){
		//create small cards
		(3..6).each{it->
			Modification m1 = new Modification(amount:it*10,operation:"+",share:s).save(failOnError: true);
			Modification m2 = new Modification(amount:(9-it)*10,operation:"-",share:null).save(failOnError: true);
			
			new Card(isRisk:false, modifications:[m1,m2]).save(failOnError: true);
		}
		(3..6).each{it->
			Modification m1 = new Modification(amount:it*10,operation:"+",share:null).save(failOnError: true);
			Modification m2 = new Modification(amount:(9-it)*10,operation:"-",share:s).save(failOnError: true);
			
			new Card(isRisk:false, modifications:[m1,m2]).save(failOnError: true);
		}
		//create big cards
		1.each{it->
			Modification m1 = new Modification(amount:2,operation:"x",share:s).save(failOnError: true);
			Modification m2 = new Modification(amount:0.5,operation:"x",share:null).save(failOnError: true);
			new Card(isRisk:false, modifications:[m1,m2]).save(failOnError: true);
		}
		1.each{it->
			Modification m1 = new Modification(amount:2,operation:"x",share:null).save(failOnError: true);
			Modification m2 = new Modification(amount:1/2,operation:"x",share:s).save(failOnError: true);
			new Card(isRisk:false, modifications:[m1,m2]).save(failOnError: true);
		}
		(2..3).each{it->
			Modification m1 = new Modification(amount:100,operation:"+",share:s).save(failOnError: true);
			def mods = [m1]
			Share.list().each{share->
				if(!share.equals(s)){
					mods.add(new Modification(amount:it*10,operation:"-",share:share).save(failOnError: true))
					
				}
			}
			new Card(isRisk:false, modifications:mods).save(failOnError: true);
		}
		
		
	}
	
	@Transactional
	public Card getNextCard(){
		Game game = gameService.getActiveGame()
		def i = (int)(Math.random() * game.unusedCards.size())
		Card card = game.unusedCards.toList()[i]
		game.activeCards.add(card)
		game.unusedCards.remove(card)
		
		game.save()
		return card
	}
	
	@Transactional
	public void executeCard(def cardId, Player player){
		Card card = Card.get(cardId)
		card.modifications.each{it->
			exectuteModification(it.id)
		}
		// mark card as used
		Game game = gameService.getActiveGame()
		game.activeCards.remove(card)
		game.usedCards.add(card)
		game.save(failOnError: true)
		
		// remove this card from users deck
		player.cards.remove(card)
		player.save(failOnError: true)
		
		String note = "played card (${card.id})"
		gameService.addHistory(note,player)
		log.info("Card was executed: " + card)
	}
	
	private void exectuteModification(def modId){
		Modification mod = Modification.get(modId)
		Share share = mod.share
		int p = share.price
		int newP = p
		def op = mod.operation
		if ("x".equals(op)){
			newP = p * mod.amount
		}else if ("-".equals(op)){
			newP = p - mod.amount
		}else {
			newP = p + mod.amount
		}
		//round to 10
		newP = newP / 10 
		newP = newP * 10
		
		if(newP > 250){ // TODO make 250 as parameter
			executeCompensation(share, newP - 250)
			newP = 250
		}
		if(newP < 10){ // TODO make 10 as parameter
			executeCompensation(share, newP - 10)
			newP = 10
		}
		
		share.price = newP
		share.save(failOnError:true)
	}
	
	private void executeCompensation(Share share, int difference){
		def exchangeList = Exchange.findAllWhere([
				share:share
			])
		for(Exchange exchange : exchangeList){
			exchange.player.cash += difference * exchange.quantity
			exchange.player.save()
		}
	}
}
